#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <iostream>
#include <thread>
#include <atomic>
#include <cstring>

std::atomic<bool> stop_thread(false);

void keyboard_event_listener(const char* device_path) {
    int fd = open(device_path, O_RDONLY);
    if (fd == -1) {
        std::cerr << "无法打开输入设备: " << device_path << " - " << strerror(errno) << std::endl;
        return;
    }

    struct input_event ev;
    std::cout << "开始监听键盘事件..." << std::endl;

    while (!stop_thread) {
        // select() 可以监听文件描述符是否可读，并设置超时时间，避免忙等待
        // 设置超时时间（例如 100 毫秒）
        fd_set fds;
        FD_ZERO(&fds);
        FD_SET(fd, &fds);
        struct timeval timeout;
        timeout.tv_sec = 0;
        timeout.tv_usec = 200000;  // 200ms

        // 等待设备可读或超时
        int ret = select(fd + 1, &fds, nullptr, nullptr, &timeout);
        if (ret == -1) {
            std::cerr << "select 错误: " << strerror(errno) << std::endl;
            break;
        } else if (ret == 0) {
            // 超时，继续循环
            continue;
        }
        ssize_t bytes = read(fd, &ev, sizeof(ev));
        if (bytes == -1) {
            if (errno == EINTR) continue;
            std::cerr << "读取错误: " << strerror(errno) << std::endl;
            break;
        }

        if (bytes != sizeof(ev)) {
            std::cerr << "读取不完整的事件" << std::endl;
            continue;
        }

        // 只处理按键事件
        if (ev.type == EV_KEY) {
            // 获取按键状态
            const char* key_state;
            switch (ev.value) {
                case 0: key_state = "释放"; break;
                case 1: key_state = "按下"; break;
                case 2: key_state = "重复"; break;
                default: key_state = "未知"; break;
            }

            // 获取按键名称
            const char* key_name;
            switch (ev.code) {
                case KEY_ESC: key_name = "ESC"; break;
                case KEY_ENTER: key_name = "ENTER"; break;
                case KEY_SPACE: key_name = "SPACE"; break;
                // 添加更多按键映射...
                default: key_name = "PTT"; break;
            }

            std::cout << "按键事件: " << key_name 
                      << " 状态: " << key_state 
                      << " 代码: " << ev.code << std::endl;
        }
    }

    close(fd);
}

int main() {
    // 通常键盘设备是 /dev/input/eventX，需要确定正确的X值
    const char* keyboard_device = "/dev/input/event0";
    
    // 启动监听线程
    std::thread listener_thread(keyboard_event_listener, keyboard_device);
    
    std::cout << "监听线程已启动，按任意键继续..." << std::endl;
    // 等待用户输入
    std::cin.get(); 
    
    // 停止线程
    stop_thread = true;
    listener_thread.join();
    
    std::cout << "程序结束" << std::endl;
    return 0;
}